﻿using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing.Drawing2D;

namespace hxc
{
    internal abstract class _Disposable : IDisposable
    {
        protected bool disposed;
        protected abstract void Dispose(bool disposing);
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }
}

namespace hxc.Win32
{
	[StructLayout(LayoutKind.Explicit, Size = 8)]
	public struct LARGE_INTEGER
	{
		[FieldOffset(0)]
		public uint LowPart;
		[FieldOffset(4)]
		public int HightPart;
		[FieldOffset(0)]
		public long QuadPart;
	}

	[StructLayout(LayoutKind.Explicit, Size = 8)]
	public struct ULARGE_INTEGER
	{
		[FieldOffset(0)]
		public uint LowPart;
		[FieldOffset(4)]
		public uint HightPart;
		[FieldOffset(0)]
		public ulong QuadPart;
	}

    [StructLayout(LayoutKind.Sequential)]
    public struct FILETIME
    {
        public uint DateTimeLow;
        public uint DateTimeHigh;
    }

	public static class User32
	{
		[StructLayout(LayoutKind.Sequential)]
		public struct NMHDR
		{
			IntPtr hwndFrom;
			UIntPtr idFrom;
			uint code;
		}

		[StructLayout(LayoutKind.Sequential)]
		struct NMCUSTOMDRAW
		{
			NMHDR hdr;
			uint dwDrawStage;
			IntPtr hdc;
			GDI32.RECT rc;
			UIntPtr dwItemSpec;
			uint uItemState;
			IntPtr lItemlParam;
		}

		[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
		public struct LVITEMW
		{
			public LVIF mask;
			public int iItem;
			public int iSubItem;
			public LVIS state;
			public uint stateMask;
			[MarshalAs(UnmanagedType.LPWStr)]
			public StringBuilder pszText;
			public int cchTextMax;
			public int iImage;
			public IntPtr lParam;		//LPARAM
			public int iIndent;
			public int iGroupId;
			public uint cColumns;		// tile view columns
			public IntPtr puColumns;	//PUINT
			public IntPtr piColFmt;	//PINT
			public int iGroup;
		}

		public const int WM_NOTIFY = 0x004E;
		public const int WM_REFLECT_BASE = 0xBC00;

		//TreeView
		public const int TV_FIRST = 0x1100;

		public const int TVM_SETIMAGELIST = TV_FIRST + 9;
		public const int TVSIL_NORMAL = 0;
		public const int TVSIL_STATE = 2;

		//ListView
		public const int LVM_FIRST = 0x1000;

		public const int LVM_SETIMAGELIST = LVM_FIRST + 3;
		public const int LVSIL_NORMAL = 0;
		public const int LVSIL_SMALL = 1;
		public const int LVSIL_STATE = 2;
		public const int LVSIL_GROUPHEADER = 3;

		public const int LVM_GETITEM = LVM_FIRST + 75;
		public const int LVM_SETITEM = LVM_FIRST + 76;


		public enum WndStyle : uint
		{
			//Window Styles
			WS_OVERLAPPED = 0,
			WS_POPUP = 0x80000000,
			WS_CHILD = 0x40000000,
			WS_MINIMIZE = 0x20000000,
			WS_VISIBLE = 0x10000000,
			WS_DISABLED = 0x08000000,
			WS_CLIPSIBLINGS = 0x04000000,
			WS_CLIPCHILDREN = 0x02000000,
			WS_MAXIMIZE = 0x01000000,
			WS_CAPTION = 0x00C00000,     /* WS_BORDER | WS_DLGFRAME  */
			WS_BORDER = 0x00800000,
			WS_DLGFRAME = 0x00400000,
			WS_VSCROLL = 0x00200000,
			WS_HSCROLL = 0x00100000,
			WS_SYSMENU = 0x00080000,
			WS_THICKFRAME = 0x00040000,
			WS_GROUP = 0x00020000,
			WS_TABSTOP = 0x00010000,

			WS_MINIMIZEBOX = 0x00020000,
			WS_MAXIMIZEBOX = 0x00010000,


			WS_TILED = WS_OVERLAPPED,
			WS_ICONIC = WS_MINIMIZE,
			WS_SIZEBOX = WS_THICKFRAME,
			WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW,

			//Common Window Styles
			WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED |
										 WS_CAPTION |
										 WS_SYSMENU |
										 WS_THICKFRAME |
										 WS_MINIMIZEBOX |
										 WS_MAXIMIZEBOX),

			WS_POPUPWINDOW = (WS_POPUP |
										 WS_BORDER |
										 WS_SYSMENU),

			WS_CHILDWINDOW = WS_CHILD,
			
			//Extended Window Styles

			WS_EX_DLGMODALFRAME = 0x00000001,
			WS_EX_NOPARENTNOTIFY = 0x00000004,
			WS_EX_TOPMOST = 0x00000008,
			WS_EX_ACCEPTFILES = 0x00000010,
			WS_EX_TRANSPARENT = 0x00000020,
			WS_EX_MDICHILD = 0x00000040,
			WS_EX_TOOLWINDOW = 0x00000080,
			WS_EX_WINDOWEDGE = 0x00000100,
			WS_EX_CLIENTEDGE = 0x00000200,
			WS_EX_CONTEXTHELP = 0x00000400,
			WS_EX_RIGHT = 0x00001000,
			WS_EX_LEFT = 0x00000000,
			WS_EX_RTLREADING = 0x00002000,
			WS_EX_LTRREADING = 0x00000000,
			WS_EX_LEFTSCROLLBAR = 0x00004000,
			WS_EX_RIGHTSCROLLBAR = 0x00000000,

			WS_EX_CONTROLPARENT = 0x00010000,
			WS_EX_STATICEDGE = 0x00020000,
			WS_EX_APPWINDOW = 0x00040000,


			WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE),
			WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST),

			WS_EX_LAYERED = 0x00080000,

			WS_EX_NOINHERITLAYOUT = 0x00100000, // Disable inheritence of mirroring by children
			WS_EX_LAYOUTRTL = 0x00400000, // Right to left mirroring

			WS_EX_COMPOSITED = 0x02000000,
			WS_EX_NOACTIVATE = 0x08000000
		}

		public enum SW_Param
		{
			SW_HIDE = 0,
			SW_SHOWNORMAL = 1,
			SW_NORMAL = 1,
			SW_SHOWMINIMIZED = 2,
			SW_SHOWMAXIMIZED = 3,
			SW_MAXIMIZE = 3,
			SW_SHOWNOACTIVATE = 4,
			SW_SHOW = 5,
			SW_MINIMIZE = 6,
			SW_SHOWMINNOACTIVE = 7,
			SW_SHOWNA = 8,
			SW_RESTORE = 9,
			SW_SHOWDEFAULT = 10,
			SW_FORCEMINIMIZE = 11,
			SW_MAX = 11
		}

		public enum GWL_Param
		{
			GWL_WNDPROC = -4,
			GWL_HINSTANCE = -6,
			GWL_HWNDPARENT = -8,
			GWL_STYLE = -16,
			GWL_EXSTYLE = -20,
			GWL_USERDATA = -21,
			GWL_ID = -12
		}

		public enum LWA_Param : uint
		{
			LWA_COLORKEY = 1,
			LWA_ALPHA = 2
		}

		public enum LVIF : uint
		{
			LVIF_DI_SETITEM = 0x1000,
			LVIF_TEXT = 0x00000001,
			LVIF_IMAGE = 0x00000002,
			LVIF_PARAM = 0x00000004,
			LVIF_STATE = 0x00000008,
			LVIF_INDENT = 0x00000010,
			LVIF_NORECOMPUTE = 0x00000800,
			LVIF_GROUPID = 0x00000100,
			LVIF_COLUMNS = 0x00000200,
			LVIF_COLFMT = 0x00010000 // The piColFmt member is valid in addition to puColumns
		}

		public enum LVIS : uint
		{
			LVIS_FOCUSED = 0x0001,
			LVIS_SELECTED = 0x0002,
			LVIS_CUT = 0x0004,
			LVIS_DROPHILITED = 0x0008,
			LVIS_GLOW = 0x0010,
			LVIS_ACTIVATING = 0x0020,
			LVIS_OVERLAYMASK = 0x0F00,
			LVIS_STATEIMAGEMASK = 0xF000,
		}

		//[DllImport("user32.dll", SetLastError=true)]
		//public static extern IntPtr CreateWindowExW(WndStyle dwExStyle, string lpClassName, string lpWindowName, WndStyle dwStyle,
		//                                int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr CreateIconFromResource(byte[] presbits, uint dwResSize, bool fIcon, uint dwVer);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr CreateIconFromResourceEx(IntPtr pbIconBits, uint cbIconBits, bool fIcon,
                                uint dwVersion, int cxDesired, int cyDesired, uint uFlags);

        public enum LoadImage_Type : uint
        {
            IMAGE_BITMAP,
            IMAGE_ICON,
            IMAGE_CURSOR
        }

        public enum LoadImage_Flag : uint
        {
            LR_DEFAULTCOLOR,
            LR_MONOCHROME,
            LR_COLOR,
            LR_COPYRETURNORG = 0x4,
            LR_COPYDELETEORG = 0x8,
            LR_LOADFROMFILE = 0x10,
            LR_LOADTRANSPARENT = 0x20,
            LR_DEFAULTSIZE = 0x40,
            LR_VGACOLOR = 0x80,
            LR_LOADMAP3DCOLORS = 0x1000,
            LR_CREATEDIBSECTION = 0x2000,
            LR_COPYFROMRESOURCE = 0x4000,
            LR_SHARED = 0x8000,
        }

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr LoadImage(IntPtr hinst, string lpszName, LoadImage_Type uType,
                        int cxDesired, int cyDesired, LoadImage_Flag fuLoad);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr LoadImage(IntPtr hinst, IntPtr lpszName, LoadImage_Type uType,
                        int cxDesired, int cyDesired, LoadImage_Flag fuLoad);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern int LookupIconIdFromDirectory(IntPtr presbits, bool fIcon);

        public enum LookupIconIdFromDirectoryExFlag
        {
            LR_DEFAULTCOLOR,
            LR_MONOCHROME
        }

        [DllImport("user32.dll", SetLastError = true)]
        public static extern int LookupIconIdFromDirectoryEx(IntPtr presbits, bool fIcon,
           int cxDesired, int cyDesired, uint Flags);

		[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

		[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        public enum MsgBoxParam
        {
            MB_OK = 0,
            MB_OKCANCEL,
            MB_ABORTRETRYIGNORE,
            MB_YESNOCANCEL,
            MB_YESNO,
            MB_RETRYCANCEL,

            MB_ICONHAND = 0x00000010,
            MB_ICONQUESTION = 0x00000020,
            MB_ICONEXCLAMATION = 0x00000030,
            MB_ICONASTERISK = 0x00000040,
            MB_USERICON = 0x00000080,
            MB_ICONWARNING = MB_ICONEXCLAMATION,
            MB_ICONERROR = MB_ICONHAND,
            MB_ICONINFORMATION = MB_ICONASTERISK,
            MB_ICONSTOP = MB_ICONHAND,

            MB_APPLMODAL = 0,
            MB_SYSTEMMODAL = 0x00001000,
            MB_TASKMODAL = 0x00002000
        }

		[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern int MessageBox(IntPtr hWnd, string msg, string title, MsgBoxParam type);

		[DllImport("user32.dll", SetLastError = true)]
		public static extern int SetWindowLong(IntPtr hWnd, GWL_Param nIndex, WndStyle NewLong);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr GetDesktopWindow();

		[DllImport("user32.dll", SetLastError = true)]
		public static extern int GetWindowLong(IntPtr hWnd, GWL_Param nIndex);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

		[DllImport("user32.dll", SetLastError = true)]
		public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

		[DllImport("user32.dll", SetLastError=true)]
		public static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, LWA_Param dwFlags);

		[DllImport("user32.dll", SetLastError = true)]
		public static extern bool DestroyIcon(IntPtr hIcon);
	}

	public static class Shlwapi
	{
        [Flags]
        public enum AssocF : uint
        {
            None = 0,
            Init_NoRemapCLSID = 0x1,
            Init_ByExeName = 0x2,
            Open_ByExeName = 0x2,
            Init_DefaultToStar = 0x4,
            Init_DefaultToFolder = 0x8,
            NoUserSettings = 0x10,
            NoTruncate = 0x20,
            Verify = 0x40,
            RemapRunDll = 0x80,
            NoFixUps = 0x100,
            IgnoreBaseClass = 0x200,
            Init_IgnoreUnknown = 0x400,
            Init_FixedProgId = 0x800,
            IsProtocol = 0x1000,
            InitForFile = 0x2000,
        }

        public enum AssocStr
        {
            Command = 1,
            Executable,
            FriendlyDocName,
            FriendlyAppName,
            NoOpen,
            ShellNewValue,
            DDECommand,
            DDEIfExec,
            DDEApplication,
            DDETopic,
            InfoTip,
            QuickTip,
            TileInfo,
            ContentType,
            DefaultIcon,
            ShellExtension,
            DropTarget,
            DelegateExecute,
            SupportedUriProtocols,
            Max,
        }

        [DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra,
                        [Out] StringBuilder pszOut, ref uint pcchOut);

        [DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool PathIsDirectory(string pszPath);

        [DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern string PathFindExtension(string Path);

		[DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern string PathFindFileName(string Path);

		[DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern string PathFindNextComponent(string Path);

        [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern int SHLoadIndirectString(string szSouce, StringBuilder sbOutBuffer, uint cchOutBuffer, IntPtr ppvReserved);
	}

	public static class Mpr
	{
		public enum RESOURCE_SCOPE
		{
			RESOURCE_CONNECTED = 0x00000001,
			RESOURCE_GLOBALNET = 0x00000002,
			RESOURCE_REMEMBERED = 0x00000003,
			RESOURCE_RECENT = 0x00000004,
			RESOURCE_CONTEXT = 0x00000005
		}

		public enum RESOURCE_TYPE
		{
			RESOURCETYPE_ANY = 0x00000000,
			RESOURCETYPE_DISK = 0x00000001,
			RESOURCETYPE_PRINT = 0x00000002,
			RESOURCETYPE_RESERVED = 0x00000008,
		}

		public enum RESOURCE_USAGE
		{
			RESOURCEUSAGE_CONNECTABLE = 0x00000001,
			RESOURCEUSAGE_CONTAINER = 0x00000002,
			RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004,
			RESOURCEUSAGE_SIBLING = 0x00000008,
			RESOURCEUSAGE_ATTACHED = 0x00000010,
			RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED),
		}

		public enum RESOURCE_DISPLAYTYPE
		{
			RESOURCEDISPLAYTYPE_GENERIC = 0x00000000,
			RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001,
			RESOURCEDISPLAYTYPE_SERVER = 0x00000002,

			RESOURCEDISPLAYTYPE_SHARE = 0x00000003,
			RESOURCEDISPLAYTYPE_FILE = 0x00000004,
			RESOURCEDISPLAYTYPE_GROUP = 0x00000005,
			RESOURCEDISPLAYTYPE_NETWORK = 0x00000006,
			RESOURCEDISPLAYTYPE_ROOT = 0x00000007,
			RESOURCEDISPLAYTYPE_SHAREADMIN = 0x00000008,
			RESOURCEDISPLAYTYPE_DIRECTORY = 0x00000009,
			RESOURCEDISPLAYTYPE_TREE = 0x0000000A,
			RESOURCEDISPLAYTYPE_NDSCONTAINER = 0x0000000B
		}

		public struct NETRESOURCE
		{
			public RESOURCE_SCOPE dwScope;
			public RESOURCE_TYPE dwType;
			public RESOURCE_DISPLAYTYPE dwDisplayType;
			public RESOURCE_USAGE dwUsage;
			[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
			public StringBuilder lpLocalName;
			[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
			public StringBuilder lpRemoteName;
			[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
			public StringBuilder lpComment;
			[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
			public StringBuilder lpProvider;
		}

		[DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)]
		private static extern int WNetEnumResource(IntPtr hEnum, ref int lpcCount, IntPtr lpBuffer, ref int lpBufferSize);

		[DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)]
		private static extern int WNetOpenEnum(RESOURCE_SCOPE dwScope, RESOURCE_TYPE dwType, RESOURCE_USAGE dwUsage,
																	[MarshalAs(UnmanagedType.AsAny)][In] Object lpNetResource, out IntPtr lphEnum);

		[DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)]
		private static extern int WNetCloseEnum(IntPtr hEnum);
	}

	public static class GDI32
	{
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int x;
            public int y;

            public POINT(int x, int y)
            {
                this.x = x;
                this.y = y;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SIZE
        {
            public int cx;
            public int cy;

            public SIZE(int cx, int cy)
            {
                this.cx = cx;
                this.cy = cy;
            }
        }

		[StructLayout(LayoutKind.Sequential)]
		public struct RECT
		{
			int left;
			int top;
			int right;
			int bottom;
		}

        [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool DeleteObject(IntPtr hObject);
	}

	public static class Kernel32
	{
		public static OperatingSystem m_OSInfo = Environment.OSVersion;

        public enum ResourceType : int
        {
            RT_CURSOR = 1,
            RT_BITMAP,
            RT_ICON,
            RT_MENU,
            RT_DIALOG,
            RT_STRING,
            RT_FONTDIR,
            RT_FONT,
            RT_ACCELERATOR,
            RT_RCDATA,
            RT_MESSAGETABLE,
            RT_GROUP_CURSOR = RT_CURSOR + 11,
            RT_GROUP_ICON = RT_ICON + 11,
            RT_VERSION = 16,
            RT_DLGINCLUDE,
            RT_PLUGPLAY = 19,
            RT_VXD,
            RT_ANICURSOR,
            RT_ANIICON,
            RT_HTML,
            RT_MANIFEST
        }

        public static bool IS_INTRESOURCE(IntPtr Value)
        {
            return (ulong)Value < ushort.MaxValue;
        }

        public delegate bool EnumResNameProc(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
        [return:MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumResourceNames(IntPtr hModule, string lpszType, EnumResNameProc lpEnumFunc, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumResourceNames(IntPtr hModule, ResourceType dwID, EnumResNameProc lpEnumFunc, IntPtr lParam);

		public enum File_Attribute : int
		{
			FILE_ATTRIBUTE_READONLY = 0x00000001,  
			FILE_ATTRIBUTE_HIDDEN = 0x00000002,  
			FILE_ATTRIBUTE_SYSTEM = 0x00000004,  
			FILE_ATTRIBUTE_DIRECTORY = 0x00000010,  
			FILE_ATTRIBUTE_ARCHIVE = 0x00000020,  
			FILE_ATTRIBUTE_DEVICE = 0x00000040,  
			FILE_ATTRIBUTE_NORMAL = 0x00000080,  
			FILE_ATTRIBUTE_TEMPORARY = 0x00000100,  
			FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200,  
			FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400,  
			FILE_ATTRIBUTE_COMPRESSED = 0x00000800,  
			FILE_ATTRIBUTE_OFFLINE = 0x00001000,  
			FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000,  
			FILE_ATTRIBUTE_ENCRYPTED = 0x00004000,  
			FILE_ATTRIBUTE_VIRTUAL = 0x00010000  
		}

		[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError = true)]
		public static extern IntPtr GetModuleHandle(string lpModuleName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindResource(IntPtr hModule, int ID, ResourceType Type);

        //[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        //public static extern IntPtr FindResource(IntPtr hModule, int lpName, string lpType);

        //[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        //public static extern IntPtr FindResource(IntPtr hModule, string lpName, int lpType);

        //[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        //public static extern IntPtr FindResource(IntPtr hModule, string lpName, string lpType);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindResourceEx(IntPtr hModule, IntPtr lpType, IntPtr lpName, ushort wLanguage);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return:MarshalAs(UnmanagedType.Bool)]
        public static extern bool FreeLibrary(IntPtr hModule);

        [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr LoadLibrary(string lpFileName);

        public enum LoadLibraryFlags
        {
            DONT_RESOLVE_DLL_REFERENCES = 0x1,
            LOAD_LIBRARY_AS_DATAFILE = 0x2,
            LOAD_WITH_ALTERED_SEARCH_PATH = 0x8,
            LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x10,
            LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x20,
            LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x40,
            LOAD_LIBRARY_REQUIRE_SIGNED_TARGET = 0x80
        }

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);

        [DllImport("kernel32.dll")]
        public static extern IntPtr LockResource(IntPtr hResData);

        [DllImport("kernel32.dll", SetLastError=true)]
        public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
	}

	public static class Dwmapi
	{
		[StructLayout(LayoutKind.Sequential)]
		public struct MARGINS
		{
			public int cxLeftWidth;      // width of left border that retains its size
			public int cxRightWidth;     // width of right border that retains its size
			public int cyTopHeight;      // height of top border that retains its size
			public int cyBottomHeight;   // height of bottom border that retains its size
		}

		[DllImport("dwmapi.dll", SetLastError=true)]
		public static extern int DwmIsCompositionEnabled(out bool bEnable);

		[DllImport("dwmapi.dll", SetLastError = true)]
		public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
	}

	public static class GdiPlus
	{
        public static GraphicsPath CreateRoundRect(int x, int y, int width, int height, int roundwidth)
		{
			GraphicsPath RoundRect = new GraphicsPath();
			RoundRect.AddArc(x, y, roundwidth, roundwidth, 180, 90); // 左上角圆弧
			RoundRect.AddLine(x + roundwidth, y, x + width - roundwidth, y); // 上边
			RoundRect.AddArc(x + width - roundwidth, y, roundwidth, roundwidth, 270, 90); // 右上角圆弧
			RoundRect.AddLine(x + width, y + roundwidth, x + width, y + height - roundwidth);// 右边
			RoundRect.AddArc(x + width - roundwidth, y + height - roundwidth, roundwidth, roundwidth, 0, 90); // 右下角圆弧
			RoundRect.AddLine(x + width - roundwidth, y + height, x + roundwidth, y + height); // 下边
			RoundRect.AddArc(x, y + height - roundwidth, roundwidth, roundwidth, 90, 90); // 左下角圆弧
			RoundRect.AddLine(x, y + roundwidth / 2, x, y + height - roundwidth);//左边
			return RoundRect;
		}
	}

    public static class Shell32
    {
        [DllImport("shell32.dll", CharSet = CharSet.Unicode, EntryPoint = "ILCreateFromPath")]
        public static extern IntPtr ILCreateFromPath(string szPath);

        [DllImport("shell32.dll", CharSet = CharSet.Unicode, EntryPoint = "ILFindLastID")]
        public static extern IntPtr ILFindLastID(IntPtr pidl);

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
        public struct SHFILEINFO
        {
            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
            public String szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public String szTypeName;
        }

		[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
		public struct OPENASINFO
		{
			[MarshalAs(UnmanagedType.LPWStr)]
			public string pcszFile;
			[MarshalAs(UnmanagedType.LPWStr)]
			public string pcszClass;
			public OPEN_AS_INFO_FLAGS oaifInFlags;
		}

		public enum OPEN_AS_INFO_FLAGS : int
		{
			OAIF_ALLOW_REGISTRATION = 0x00000001,     // enable the "always use this file" checkbox (NOTE if you don't pass this, it will be disabled)
			OAIF_REGISTER_EXT       = 0x00000002,     // do the registration after the user hits "ok"
			OAIF_EXEC               = 0x00000004,     // execute file after registering
			OAIF_FORCE_REGISTRATION = 0x00000008,     // force the "always use this file" checkbox to be checked (normally, you won't use the OAIF_ALLOW_REGISTRATION when you pass this)
			OAIF_HIDE_REGISTRATION  = 0x00000020,     // hide the "always use this file" checkbox
			OAIF_URL_PROTOCOL       = 0x00000040,
		}

		public enum SHGFI : int
		{
			SHGFI_ICON              =0x000000100,     // get icon
			SHGFI_DISPLAYNAME       =0x000000200,     // get display name
			SHGFI_TYPENAME          =0x000000400,     // get type name
			SHGFI_ATTRIBUTES        =0x000000800,     // get attributes
			SHGFI_ICONLOCATION      =0x000001000,     // get icon location
			SHGFI_EXETYPE           =0x000002000,     // return exe type
			SHGFI_SYSICONINDEX      =0x000004000,     // get system icon index
			SHGFI_LINKOVERLAY       =0x000008000,     // put a link overlay on icon
			SHGFI_SELECTED          =0x000010000,     // show icon in selected state
			SHGFI_ATTR_SPECIFIED    =0x000020000,     // get only specified attributes
			SHGFI_LARGEICON         =0x000000000,     // get large icon
			SHGFI_SMALLICON         =0x000000001,     // get small icon
			SHGFI_OPENICON          =0x000000002,     // get open icon
			SHGFI_SHELLICONSIZE     =0x000000004,     // get shell size icon
			SHGFI_PIDL              =0x000000008,     // pszPath is a pidl
			SHGFI_USEFILEATTRIBUTES =0x000000010,     // use passed dwFileAttribute

			SHGFI_ADDOVERLAYS       =0x000000020,     // apply the appropriate overlays
			SHGFI_OVERLAYINDEX      =0x000000040,     // Get the index of the overlay
													 // in the upper 8 bits of the iIcon
		}

		[DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Auto)]
		public static extern IntPtr SHGetFileInfo(string szPath, Kernel32.File_Attribute dwFileAttributes,
							ref SHFILEINFO psfi, int cbFileInfo, SHGFI uFlags);

        public enum SHImageListType : int
        {
            SHIL_LARGE,   // normally 32x32
            SHIL_SMALL,   // normally 16x16
            SHIL_EXTRALARGE,  //48x48
            SHIL_SYSSMALL,   // like SHIL_SMALL, but tracks system small icon metric correctly
            SHIL_JUMBO,   // normally 256x256
        }

        [DllImport("shell32.dll", SetLastError = true)]
        public static extern int SHGetImageList(SHImageListType iImageList, ref Guid riid, out COM.comctl32.IImageList ppv);

        [DllImport("shell32.dll", SetLastError = true)]
        public static extern int SHGetImageList(SHImageListType iImageList, ref Guid riid, out IntPtr ppv);

        [DllImport("shell32.dll", SetLastError = true, CharSet=CharSet.Auto)]
        public static extern int SHGetPathFromIDList(IntPtr pidl, StringBuilder Path);

		[DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
		private static extern void OpenAs_RunDLL(IntPtr hWnd, IntPtr hInstance, string FileName, User32.SW_Param Flag);

		[DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
		public static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile,
							string lpParameters, string lpDirectory, User32.SW_Param nShowCmd);

		[DllImport("shell32.dll", CharSet = CharSet.Unicode, EntryPoint = "SHOpenWithDialog")]
		private static extern int Shell32_SHOpenWithDialog(IntPtr hWndParent, ref OPENASINFO poainfo);

		public static void SHOpenWithDialog(IntPtr hWndParent, ref OPENASINFO poainfo)
		{
			if (Kernel32.m_OSInfo.Version.Major >= 6)
				Shell32_SHOpenWithDialog(hWndParent, ref poainfo);
			else
				OpenAs_RunDLL(hWndParent, Kernel32.GetModuleHandle(null), poainfo.pcszFile, hxc.Win32.User32.SW_Param.SW_SHOWNORMAL);
		}

        [DllImport("shell32.dll", SetLastError = true, EntryPoint = "SHGetDesktopFolder")]
        private static extern int _SHGetDesktopFolder(out IntPtr ppshf);

        public static COM.ShlObj.IShellFolder SHGetDesktopFolder()
        {
            IntPtr ppshf;
            _SHGetDesktopFolder(out ppshf);
            Object obj = Marshal.GetObjectForIUnknown(ppshf);
            Marshal.Release(ppshf);
            return (COM.ShlObj.IShellFolder)obj;
        }

        [DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern IntPtr SHBindToObject(hxc.COM.ShlObj.IShellFolder psf, IntPtr pidl, IntPtr pbc, ref Guid riid, out IntPtr ppv);

        [DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern IntPtr SHBindToParent(IntPtr pidl, ref Guid riid, out IntPtr ppv, out IntPtr ppidlLast);
    }
}

namespace hxc.COM
{
    public static class IID
    {
        public static Guid IID_IEnumIDList = Guid.Parse("000214F2-0000-0000-C000-000000000046");
        public static Guid IID_IExtractIconA = Guid.Parse("000214eb-0000-0000-c000-000000000046");
        public static Guid IID_IExtractIconW = Guid.Parse("000214fa-0000-0000-c000-000000000046");
        public static Guid IID_IImageList = Guid.Parse("46EB5926-582E-4017-9FDF-E8998DAA0950");
        public static Guid IID_IShellFolder = Guid.Parse("000214E6-0000-0000-C000-000000000046");
        public static Guid IID_IShellFolder2 = Guid.Parse("93F2F68C-1D1B-11d3-A30E-00C04F79ABD1");
        public static Guid IID_IExtractImage = Guid.Parse("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1");
        public static Guid IID_IExtractImage2 = Guid.Parse("953BB1EE-93B4-11d1-98A3-00C04FB687DA");
    }

    public static class ShlObj
    {
        public enum SFGAO : uint
        {
            SFGAO_CANCOPY = 0x00000001,
            SFGAO_CANMOVE = 0x00000002,
            SFGAO_CANLINK = 0x00000004,
            SFGAO_LINK = 0x00010000,
            SFGAO_SHARE = 0x00020000,
            SFGAO_READONLY = 0x00040000,
            SFGAO_HIDDEN = 0x00080000,
            SFGAO_FOLDER = 0x20000000,
            SFGAO_FILESYSTEM = 0x40000000,
            SFGAO_HASSUBFOLDER = 0x80000000,
        }

        public enum SHCONTF : int
        {
            SHCONTF_CHECKING_FOR_CHILDREN = 0x00010,
            SHCONTF_FOLDERS = 0x00020,
            SHCONTF_NONFOLDERS = 0x00040,
            SHCONTF_INCLUDEHIDDEN = 0x00080,
            SHCONTF_INIT_ON_FIRST_NEXT = 0x00100,
            SHCONTF_NETPRINTERSRCH = 0x00200,
            SHCONTF_SHAREABLE = 0x00400,
            SHCONTF_STORAGE = 0x00800,
            SHCONTF_NAVIGATION_ENUM = 0x01000,
            SHCONTF_FASTITEMS = 0x02000,
            SHCONTF_FLATLIST = 0x04000,
            SHCONTF_ENABLE_ASYNC = 0x08000,
            SHCONTF_INCLUDESUPERHIDDEN = 0x10000
        }

        public enum SHGDN
        {
            SHGDN_NORMAL = 0x0000,
            SHGDN_INFOLDER = 0x0001,
            SHGDN_FOREDITING = 0x1000,
            SHGDN_FORADDRESSBAR = 0x4000,
            SHGDN_FORPARSING = 0x8000,
        }

        public enum FSTRRET : int
        {
            STRRET_WSTR = 0x0000,    // Use STRRET.pOleStr
            STRRET_OFFSET = 0x0001,    // Use STRRET.uOffset to Ansi
            STRRET_CSTR = 0x0002    // Use STRRET.cStr
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct STRRET
        {
            public FSTRRET uType;
            [StructLayout(LayoutKind.Explicit, Size = 520)]
            public struct STRRETInternal
            {
                [FieldOffset(0)]
                public IntPtr pOleStr;
                [FieldOffset(0)]
                public IntPtr pStr;
                [FieldOffset(0)]
                public uint uOffset;
            }
            public STRRETInternal _Data;
            public string Data
            {
                get
                {
                    if (uType != FSTRRET.STRRET_WSTR)
                        return Marshal.PtrToStringAuto(_Data.pStr);
                    return Marshal.PtrToStringAuto(_Data.pOleStr);
                }
            }
        }

        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("000214F2-0000-0000-C000-000000000046")]
        public interface IEnumIDList
        {
            [PreserveSig]
            int Next(
                uint celt,
                out IntPtr rgelt,
                out IntPtr pceltFetched);

            [PreserveSig]
            int Skip(uint celt);

            [PreserveSig]
            int Reset();

            [PreserveSig]
            int Clone(out IEnumIDList ppenum);
        }

        [Flags]
        public enum IExtractIconuFlags : ushort
        {
            GIL_ASYNC = 0x0020,
            GIL_DEFAULTICON = 0x0040,
            GIL_FORSHELL = 0x0002,
            GIL_FORSHORTCUT = 0x0080,
            GIL_OPENICON = 0x0001,
            GIL_CHECKSHIELD = 0x0200
        }

        [Flags]
        public enum IExtractIconpwFlags : ushort
        {
            GIL_DONTCACHE = 0x0010,
            GIL_NOTFILENAME = 0x0008,
            GIL_PERCLASS = 0x0004,
            GIL_PERINSTANCE = 0x0002,
            GIL_SIMULATEDOC = 0x0001,
            GIL_SHIELD = 0x0200,//Windows Vista only
            GIL_FORCENOSHIELD = 0x0400//Windows Vista only
        }

        [Flags]
        public enum IExtractImageFlags : int
        {
            Async = 0x1,
            Cache = 0x2,
            Aspect = 0x4,
            Offline = 0x8,
            Gleam = 0x10,
            Screen = 0x20,
            OriginalSize = 0x40,
            NoStamp = 0x80,
            NoBorder = 0x100,
            Quality = 0x200
        }

        [Guid("000214fa-0000-0000-c000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IExtractIconW
        {
            [PreserveSig]
            int GetIconLocation(
                IExtractIconuFlags uFlags,
                [Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 2)]
                StringBuilder szIconFile, int cchMax, out int piIndex, out IExtractIconpwFlags pwFlags);

            [PreserveSig]
            int Extract([MarshalAs(UnmanagedType.LPWStr)] string pszFile, uint nIconIndex,
                out IntPtr phiconLarge, out IntPtr phiconSmall, uint nIconSize);
        }

        [Guid("000214eb-0000-0000-c000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IExtractIconA
        {
            [PreserveSig]
            int GetIconLocation(IExtractIconuFlags uFlags,
            [MarshalAs(UnmanagedType.LPStr)] StringBuilder szIconFile,
                       int cchMax, out int piIndex, out IExtractIconpwFlags pwFlags);

            [PreserveSig]
            int Extract([MarshalAs(UnmanagedType.LPStr)] string pszFile,
                   uint nIconIndex,
                   out IntPtr phiconLarge,
                   out IntPtr phiconSmall,
                   uint nIconSize);
        }

        [Guid("BB2E617C-0920-11d1-9A0B-00C04FC2D6C1")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IExtractImage
        {
            void GetLocation(
                [Out, MarshalAs(UnmanagedType.LPWStr)]
                StringBuilder pszPathBuffer,
                int cch,
                ref int pdwPriority,
                ref hxc.Win32.GDI32.SIZE prgSize,
                int dwRecClrDepth,
                ref int pdwFlags);

            void Extract(out IntPtr phBmpThumbnail);
        }

        [Guid("953BB1EE-93B4-11d1-98A3-00C04FB687DA")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IExtractImage2 : IExtractImage
        {
            void GetDateStamp(ref hxc.Win32.FILETIME DateStamp);
        }

        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("000214E6-0000-0000-C000-000000000046")]
        public interface IShellFolder
        {
            [PreserveSig]
            int ParseDisplayName(IntPtr hwnd, IntPtr pbc, String pszDisplayName,
                            out UInt32 pchEaten, out IntPtr ppidl, [In, Out]ref UInt32 pdwAttributes);

            [PreserveSig]
            int EnumObjects(IntPtr hwnd, SHCONTF grfFlags, out IEnumIDList ppenumIDList);

            [PreserveSig]
            int BindToObject(IntPtr pidl, IntPtr pbc, [In]ref Guid riid, out IntPtr ppv);

            [PreserveSig]
            int BindToStorage(IntPtr pidl, IntPtr pbc, [In]ref Guid riid, out IntPtr ppv);

            [PreserveSig]
            int CompareIDs(Int32 lParam, IntPtr pidl1, IntPtr pidl2);

            [PreserveSig]
            int CreateViewObject(IntPtr hwndOwner, [In] ref Guid riid, out IntPtr ppv);

            [PreserveSig]
            int GetAttributesOf(UInt32 cidl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]IntPtr[] apidl,
                                ref SFGAO rgfInOut);

            [PreserveSig]
            int GetUIObjectOf(IntPtr hwndOwner, UInt32 cidl,
                                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]IntPtr[] apidl,
                                [In] ref Guid riid, UInt32 rgfReserved, out IntPtr ppv);

            [PreserveSig]
            int GetDisplayNameOf(IntPtr pidl, SHGDN uFlags, out STRRET pName);

            [PreserveSig]
            int SetNameOf(IntPtr hwnd, IntPtr pidl, String pszName, SHCONTF uFlags, out IntPtr ppidlOut);
        }

        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("93F2F68C-1D1B-11d3-A30E-00C04F79ABD1")]
        public interface IShellFolder2 : IShellFolder
        {
            [PreserveSig]
            int GetDefaultSearchGUID(out Guid pguid);
        }
    }

    public class comctl32
    {
        public enum IMAGELISTDRAWPARAMSFlag : uint
        {
            ILD_NORMAL = 0x00000000,
            ILD_TRANSPARENT = 0x00000001,
            ILD_MASK = 0x00000010,
            ILD_IMAGE = 0x00000020,
            ILD_ROP = 0x00000040,
            ILD_BLEND25 = 0x00000002,
            ILD_BLEND50 = 0x00000004,
            ILD_OVERLAYMASK = 0x00000F00,
            ILD_PRESERVEALPHA = 0x00001000,  // This preserves the alpha channel in dest
            ILD_SCALE = 0x00002000,  // Causes the image to be scaled to cx, cy instead of clipped
            ILD_DPISCALE = 0x00004000,
            ILD_ASYNC = 0x00008000,
            ILD_SELECTED = ILD_BLEND50,
            ILD_FOCUS = ILD_BLEND25,
            ILD_BLEND = ILD_BLEND50
        };

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGELISTDRAWPARAMS
        {
            public uint cbSize;
            public IntPtr himl;
            public int i;
            public IntPtr hdcDst;
            public int x;
            public int y;
            public int cx;
            public int cy;
            public int xBitmap;
            public int yBitmap;
            public uint rgbBk;
            public uint rgbFg;
            public uint fStyle;
            public uint dwRop;
            public uint fState;
            public uint Frame;
            public uint crEffect;
        };

        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGEINFO
        {
            public IntPtr hbmImage;
            public IntPtr hbmMask;
            public int Unused1;
            public int Unused2;
            public Win32.GDI32.RECT rcImage;
        };

        public enum IImageListItemFlags : uint
        {
            ILIF_ALPHA,
            ILIF_LOWQUALITY
        };

        [Guid("46EB5926-582E-4017-9FDF-E8998DAA0950")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IImageList
        {
            [PreserveSig] int Add(IntPtr hbmImage, IntPtr hbmMask, out int pi);
            [PreserveSig] int ReplaceIcon(int i, IntPtr hicon, out int pi);
            [PreserveSig] int SetOverlayImage(int iImage, int iOverlay);
            [PreserveSig] int Replace(int i, IntPtr hbmImage, IntPtr hbmMask);
            [PreserveSig] int AddMasked(IntPtr hbmImage, uint crMask, out int pi);
            [PreserveSig] int Draw(ref IMAGELISTDRAWPARAMS pimldp);
            [PreserveSig] int Remove(int i);
            [PreserveSig] int GetIcon(int i, IMAGELISTDRAWPARAMSFlag flags, out IntPtr picon);
            [PreserveSig] int GetImageInfo(int i, ref IMAGEINFO pImageInfo);
            [PreserveSig] int Copy(int iDst, IImageList punkSrc, int iSrc, uint uFlags);
            [PreserveSig] int Merge(int i1, IntPtr punk2, int i2, int dx, int dy, [In]ref Guid riid, out IntPtr ppv);
            [PreserveSig] int Clone([In]ref Guid riid, out IImageList ppv);
            [PreserveSig] int GetImageRect(int i, ref Win32.GDI32.RECT prc);
            [PreserveSig] int GetIconSize(out int cx, out int cy);
            [PreserveSig] int SetIconSize(int cx, int cy);
            [PreserveSig] int GetImageCount(out int pi);
            [PreserveSig] int SetImageCount(uint uNewCount);
            [PreserveSig] int SetBkColor(uint clrBk, out uint pclr);
            [PreserveSig] int GetBkColor(out uint pclr);
            [PreserveSig] int BeginDrag(int iTrack, int dxHotspot, int dyHotspot);
            [PreserveSig] int EndDrag();
            [PreserveSig] int DragEnter(IntPtr hwndLock, int x, int y);
            [PreserveSig] int DragLeave(IntPtr hwndLock);
            [PreserveSig] int DragMove(int x, int y);
            [PreserveSig] int SetDragCursorImage(IntPtr punk, int iDrag, int dxHotspot, int dyHotspot);
            [PreserveSig] int DragShowNolock(bool fShow);
            [PreserveSig] int GetDragImage(Win32.GDI32.POINT ppt, Win32.GDI32.POINT pptHotspot,
                                                    [In]ref Guid riid, out IntPtr ppv);
            [PreserveSig] int GetItemFlags(int i, out IImageListItemFlags dwFlags);
            [PreserveSig] int GetOverlayImage(int iOverlay, out int piIndex);
            
            
            
            
            
        };
    };
}